/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sle_ssap_client_stub.h"
#include "sle_hilog.h"

namespace OHOS {
namespace NearLink {
namespace SleStandard {
SleSsapClientStub::SleSsapClientStub()
{
    memberFuncMap_[SleSsapClientInterfaceCode::SLE_SSAP_CLIENT_REGISTER_CLIENT] =
        &SleSsapClientStub::RegisterSsapClientInner;
    memberFuncMap_[SleSsapClientInterfaceCode::SLE_SSAP_CLIENT_UNREGISTER_CLIENT] =
        &SleSsapClientStub::UnregisterSsapClientInner;
    memberFuncMap_[SleSsapClientInterfaceCode::SLE_SSAP_CLIENT_FIND_STRUCTURE] =
        &SleSsapClientStub::FindSsapStructureInner;
    memberFuncMap_[SleSsapClientInterfaceCode::SLE_SSAP_CLIENT_READ_REQUEST_BY_UUID] =
        &SleSsapClientStub::ReadRequestByUuidInner;
    memberFuncMap_[SleSsapClientInterfaceCode::SLE_SSAP_CLIENT_READ_REQUEST] =
        &SleSsapClientStub::ReadRequestInner;
    memberFuncMap_[SleSsapClientInterfaceCode::SLE_SSAP_CLIENT_WRITE_REQUEST] =
        &SleSsapClientStub::WriteRequestInner;
    memberFuncMap_[SleSsapClientInterfaceCode::SLE_SSAP_CLIENT_WRITE_COMMAND] =
        &SleSsapClientStub::WriteCommandInner;
    memberFuncMap_[SleSsapClientInterfaceCode::SLE_SSAP_CLIENT_EXCHANGE_REQUEST] =
        &SleSsapClientStub::ExchangeInfoInner;
}

SleSsapClientStub::~SleSsapClientStub(){}

int SleSsapClientStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
    if(code != SLE_SSAP_CLIENT_WRITE_REQUEST && code != SLE_SSAP_CLIENT_WRITE_COMMAND) {
        SLE_LOGD("cmd = %{public}d, flags= %{public}d", code, option.GetFlags());
    }
    std::u16string descriptor = SleSsapClientStub::GetDescriptor();
    std::u16string remoteDescriptor = data.ReadInterfaceToken();
    SLE_ASSERT_AND_RETURN_RET_LOG(descriptor == remoteDescriptor, ERR_INVALID_STATE, "local descriptor is not equal to remote error!");

    auto itFunc = memberFuncMap_.find((SleSsapClientInterfaceCode)code);
    if (itFunc != memberFuncMap_.end()) {
        auto memberFunc = itFunc->second;
        if (memberFunc != nullptr) {
            return (this->*memberFunc)(data, reply);
        }
    }
    SLE_LOGW("default case, need check.");
    return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}

int SleSsapClientStub::RegisterSsapClientInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("RegisterSsapClientInner In");
    std::shared_ptr<Uuid> uuid(data.ReadParcelable<Uuid>());
    SLE_ASSERT_AND_RETURN_RET_LOG(uuid, TRANSACTION_ERR, "read client uuid failed!");

    sptr<IRemoteObject> remote = data.ReadRemoteObject();
    SLE_ASSERT_AND_RETURN_RET_LOG(remote, TRANSACTION_ERR, "read client remote failed!");
    const sptr<ISleSsapClientCallback> callback = OHOS::iface_cast<ISleSsapClientCallback>(remote);
    SLE_ASSERT_AND_RETURN_RET_LOG(callback, TRANSACTION_ERR, "read client callback failed!");

    uint8_t clientId;
    int32_t result = RegisterSsapClient(*uuid, clientId, callback);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteUint8(clientId), TRANSACTION_ERR, "write client id back failed!");
    return NO_ERROR;
}

int SleSsapClientStub::UnregisterSsapClientInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("UnregisterSsapClientInner In");
    uint8_t clientId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(clientId), TRANSACTION_ERR, "read client id failed!");

    sptr<IRemoteObject> remote = data.ReadRemoteObject();
    SLE_ASSERT_AND_RETURN_RET_LOG(remote, TRANSACTION_ERR, "read client remote failed!");
    const sptr<ISleSsapClientCallback> callback = OHOS::iface_cast<ISleSsapClientCallback>(remote);
    SLE_ASSERT_AND_RETURN_RET_LOG(callback, TRANSACTION_ERR, "read client callback failed!");

    int32_t result = UnregisterSsapClient(clientId, callback);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapClientStub::FindSsapStructureInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("FindSsapStructureInner In");
    uint8_t clientId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(clientId), TRANSACTION_ERR, "read client id failed!");

    uint16_t connectId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(connectId), TRANSACTION_ERR, "read connect id failed!");

    std::shared_ptr<SsapClientFindStructure> param(data.ReadParcelable<SsapClientFindStructure>());
    SLE_ASSERT_AND_RETURN_RET_LOG(param, TRANSACTION_ERR, "read find structure param failed!");

    int32_t result = FindSsapStructure(clientId, connectId, *param);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapClientStub::ReadRequestByUuidInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("ReadRequestByUuidInner In");
    uint8_t clientId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(clientId), TRANSACTION_ERR, "read client id failed!");

    uint16_t connectId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(connectId), TRANSACTION_ERR, "read connect id failed!");

    std::shared_ptr<SsapClientReadReqByUUID> param(data.ReadParcelable<SsapClientReadReqByUUID>());
    SLE_ASSERT_AND_RETURN_RET_LOG(param, TRANSACTION_ERR, "read read param failed!");

    int32_t result = ReadRequestByUuid(clientId, connectId, *param);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapClientStub::ReadRequestInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("ReadRequestInner In");
    uint8_t clientId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(clientId), TRANSACTION_ERR, "read client id failed!");

    uint16_t connectId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(connectId), TRANSACTION_ERR, "read connect id failed!");

    uint16_t handle;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(handle), TRANSACTION_ERR, "read read handle failed!");

    uint8_t type;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(type), TRANSACTION_ERR, "read read type failed!");

    int32_t result = ReadRequest(clientId, connectId, handle, type);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapClientStub::WriteRequestInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("WriteRequestInner In");
    uint8_t clientId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(clientId), TRANSACTION_ERR, "read client id failed!");

    uint16_t connectId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(connectId), TRANSACTION_ERR, "read connect id failed!");

    std::shared_ptr<SsapClientHandleValue> param(data.ReadParcelable<SsapClientHandleValue>());
    SLE_ASSERT_AND_RETURN_RET_LOG(param, TRANSACTION_ERR, "read write param failed!");

    int32_t result = WriteRequest(clientId, connectId, *param);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapClientStub::WriteCommandInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("WriteCommandInner In");
    uint8_t clientId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(clientId), TRANSACTION_ERR, "read client id failed!");

    uint16_t connectId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(connectId), TRANSACTION_ERR, "read connect id failed!");

    std::shared_ptr<SsapClientHandleValue> param(data.ReadParcelable<SsapClientHandleValue>());
    SLE_ASSERT_AND_RETURN_RET_LOG(param, TRANSACTION_ERR, "read write param failed!");

    int32_t result = WriteCommand(clientId, connectId, *param);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapClientStub::ExchangeInfoInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("ExchangeInfoInner In");
    uint8_t clientId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(clientId), TRANSACTION_ERR, "read client id failed!");

    uint16_t connectId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(connectId), TRANSACTION_ERR, "read connect id failed!");

    uint32_t mtu;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint32(mtu), TRANSACTION_ERR, "read mtu failed!");

    uint16_t version;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(version), TRANSACTION_ERR, "read version failed!");

    int32_t result = ExchangeInfo(clientId, connectId, mtu, version);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}
} // SleStandard
} // NearLink
} // OHOS